package com.ifonly.logger;

import com.ifonly.logger.nop.NOPLoggerFactory;

/**
 * Logger
 *
 *  日志类, 对常用日志接口的抽象
 *
 * @author <a href="mailto:ifonlymaster@163.com">ifonly</a>
 * @version 1.0 2015-12-09 09:52
 * @since JDK 1.6
 */
public abstract class Logger {
    /**
     * 日志级别
     */
    public enum Level {
        TRACE(1),
        DEBUG(2),
        INFO(3),
        WARN(4),
        ERROR(5);

        private final int value;

        Level(int value) {
            this.value = value;
        }

        /**
         * 是否支持指定的日志级别
         *
         * @param level 日志级别
         * @return true-支持|false-不支持
         */
        public boolean isEnabledFor(Level level) {
            return this.value >= level.value;
        }
    }

    /**
     * 日志名称
     */
    protected String name;

    /**
     * 获取日志名称
     *
     * @return 日志名称
     */
    public String getName() {
        return this.name;
    }

    /**
     * ILoggerFactory 用于获取 Logger
     */
    private static ILoggerFactory factory = new NOPLoggerFactory();

    /**
     * 设置 日志工厂 对象
     *
     * @param factoryClassName ILoggerFactory 实现类类名
     */
    @SuppressWarnings("unchecked")
    public static void setLoggerFactory(String factoryClassName) {
        try {
            Class<? extends ILoggerFactory> factoryClass = (Class<? extends ILoggerFactory>) Class.forName(factoryClassName);
            ILoggerFactory factory = factoryClass.newInstance();
            setLoggerFactory(factory);
        } catch (ClassNotFoundException e) {
            throw new IllegalArgumentException("Class ["+ factoryClassName +"] not found...", e);
        } catch (InstantiationException e) {
            throw new IllegalArgumentException("New instance of Class ["+ factoryClassName +"] failed...", e);
        } catch (IllegalAccessException e) {
            throw new IllegalArgumentException("New instance of Class ["+ factoryClassName +"] failed...", e);
        }
    }

    /**
     * 设置 日志工厂 对象
     *
     * @param factory ILoggerFactory 对象
     */
    public static void setLoggerFactory(ILoggerFactory factory) {
        Logger.factory = factory;
    }

    /**
     * 通过 name 获取 Logger
     *
     * @param name 名称
     * @return Logger 对象
     */
    public static Logger getLogger(String name) {
        return factory.getLogger(name);
    }

    /**
     * 通过 clazz 获取 Logger
     *
     * @param clazz 类对象
     * @return Logger 对象
     */
    public static Logger getLogger(Class<?> clazz) {
        return factory.getLogger(clazz);
    }

    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ abstract methods

    /**
     * 是否支持指定日志级别
     *
     * @param level 日志级别
     * @return true-支持|false-不支持
     */
    public abstract boolean isEnabled(Level level);

    /**
     * 记录指定级别的日志信息
     *
     * @param level 日志级别
     * @param message 日志信息
     */
    public abstract void log(Level level, String message);


    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TRACE

    /**
     * 是否支持 trace 级别日志处理
     *
     * @return true-支持|false-不支持
     */
    public abstract boolean isTraceEnabled();

    /**
     * trace 级别日志记录
     *
     * @param message 日志信息
     */
    public abstract void trace(String message);

    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DEBUG

    /**
     * 是否支持 debug 级别日志处理
     *
     * @return true-支持|false-不支持
     */
    public abstract boolean isDebugEnabled();

    /**
     * debug 级别日志记录
     *
     * @param message 日志信息
     */
    public abstract void debug(String message);

    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ INFO

    /**
     * 是否支持 info 级别日志处理
     *
     * @return true-支持|false-不支持
     */
    public abstract boolean isInfoEnabled();

    /**
     * info 级别日志记录
     *
     * @param message 日志信息
     */
    public abstract void info(String message);

    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ WARN

    /**
     * 是否支持 warn 级别日志处理
     *
     * @return true-支持|false-不支持
     */
    public abstract boolean isWarnEnabled();

    /**
     * warn 级别日志记录
     *
     * @param message 日志信息
     */
    public abstract void warn(String message);

    /**
     * info 级别日志记录
     *
     * @param message 日志信息
     * @param throwable Throwable对象
     */
    public abstract void warn(String message, Throwable throwable);

    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ERROR

    /**
     * 是否支持 error 级别日志处理
     *
     * @return true-支持|false-不支持
     */
    public abstract boolean isErrorEnabled();

    /**
     * error 级别日志记录
     *
     * @param message 日志信息
     */
    public abstract void error(String message);

    /**
     * error 级别日志记录
     *
     * @param message 日志信息
     * @param throwable Throwable对象
     */
    public abstract void error(String message, Throwable throwable);



}
